package cn.tedu.api;
//测试  多线程售票
//2 需求：设计4个窗口，总计售票100张
public class Test1 {
    public static void main(String[] args) {
        //TODO 问题1：总共要卖100张票，现在卖了400张，为什么？
        //原因是：int tickets =100，是成员变量，是每个对象初始化都要储存的，四个对象存了4份
        //要怎么解决----想办法让成员变量变成  多个对象间的共享的资源，保证全局统一
        MyTickets t = new MyTickets();
        MyTickets t2 = new MyTickets();
        MyTickets t3 = new MyTickets();
        MyTickets t4 = new MyTickets();
        t.start();
        t2.start();
        t3.start();
        t4.start();


    }
}
//
class MyTickets  extends  Thread{
    //TODO 问题1 ：加上static把票变成共享资源，而不是人手一份
    static int tickets = 100;//定义变量，记录票数
    //准备卖票，把业务放入重写的run()
    @Override
//
//
//    synchronized public void run() {TODO 3方法被同步后，会自动分配锁对象，普通方法的锁对象默认是this。
                                       //静态方法的锁对象才是  类名.class
        public void run() {
        while (true){//只要有票就一直卖
            //TODO 考验,多线程编程中的数据到底安全不？？？---sleep()
            synchronized(MyTickets.class) {//TODO 1锁对象怎么分配----看你的共享资源是普通的还是静态的
                                           //TODO 2 静态资源的锁对象才是类名.class
                if (tickets > 0) {
                    try {
                        //问题2  重卖---出现了同一张票卖给了多个人
                        //问题3  超卖---卖出了0 -1 -2 号票
                        //原因？？？
                        //超卖的原因:
                        //假设t1先醒,开始卖票,执行tickets--,输出1,自减变成0
                        //假设t2醒了,开始卖票,执行tickets--,输出0,自减变成-1
                        //假设t3醒了,开始卖票,执行tickets--,输出-1,自减变成-2
                        //假设t4醒了,开始卖票,执行tickets--,输出-2,自减变成-3

                        //重卖的原因:
                        //假设t1先醒,开始卖票,执行tickets--,输出80 没来得及变
                        //假设t2醒了,开始卖票,执行tickets--,输出80 没来得及变
                        //假设t3醒了,开始卖票,执行tickets--,输出80 自减变成79
                        //假设t4醒了,开始卖票,执行tickets--,输出79....
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(super.getName() + "  " + tickets--);
                } else {
                    break;
                }
            }
        }
    }
}
